﻿using System;
using System.Collections.Generic;
using System.Drawing;
using System.Text;
using NUnit.Framework;
using Savage.DotNetLibrary.ImageLibrary;

namespace Savage.DotNetLibrary.TestDotNetLibrary.ImageLibraryTests
{
    [TestFixture]
    public class TestExif
    {
        [Test]
        [ExpectedException(typeof(ArgumentNullException))]
        public void TestExifArgumentNull()
        {
            ImageLibrary.Exif exif = new Exif(null);
        }

        
        [Test]
        public void TestExifPropertiesTest1()
        {
            Bitmap bmp = new Bitmap("Samples/test1.jpg");
            Exif exif = new Exif(bmp);

            Assert.AreEqual(null, exif.Artist);
            Assert.AreEqual(null, exif.BitsPerSample);
            Assert.AreEqual(ExifColorSpace.sRGB, exif.ColorSpace);
            Assert.AreEqual(TiffCompression.NotSpecified, exif.Compression);
            Assert.AreEqual(null, exif.Copyright);
            Assert.AreEqual(new DateTime(2007, 11, 12, 7, 31, 56), exif.DateTimeDigitized);
            Assert.AreEqual(new DateTime(2007, 11, 12, 7, 31, 56), exif.DateTimeOriginal);
            Assert.AreEqual("0220", exif.ExifVersion);
            Assert.AreEqual(ExifExposureProgram.NormalProgram, exif.ExposureProgram);
            Assert.AreEqual(null, exif.FileChangeDateTime);
            Assert.AreEqual("0100", exif.FlashpixVersion);
            Assert.AreEqual(null, exif.GPSData);
            Assert.AreEqual(null, exif.ImageDescription);
            Assert.AreEqual(null, exif.ImageHeight);
            Assert.AreEqual(null, exif.ImageUniqueId);
            Assert.AreEqual(null, exif.ImageWidth);
            Assert.AreEqual(2708, exif.JpegInterchangeFormat);
            Assert.AreEqual(3995, exif.JpegInterchangeFormatLength);
            Assert.AreEqual("EASTMAN KODAK COMPANY", exif.Make);
            //Just test that the content is the same length
            Assert.AreEqual(1287, exif.MakerNote.Length);
            Assert.AreEqual("KODAK DX6340 ZOOM DIGITAL CAMERA", exif.Model);
            Assert.AreEqual(TiffOrientation.TopLeft, exif.Orientation);
            Assert.AreEqual(TiffPhotometricInterpolation.NotSpecified, exif.PhotometricInterpolation);
            Assert.AreEqual(2032, exif.PixelXDimension);
            Assert.AreEqual(1524, exif.PixelYDimension);
            Assert.AreEqual(TiffPlanarConfiguration.NotSpecified, exif.PlanarConfiguration);
            Assert.AreEqual(TiffResolutionUnit.Inches, exif.ResolutionUnit);
            Assert.AreEqual(null, exif.RowsPerStrip);
            Assert.AreEqual(null, exif.SamplesPerPixel);
            Assert.AreEqual(null, exif.Software);
            Assert.AreEqual(null, exif.StripByteCounts);
            Assert.AreEqual(null, exif.StripOffsets);
            Assert.AreEqual(null, exif.SubsecDigitized);
            Assert.AreEqual(null, exif.SubsecOriginal);
            Assert.AreEqual(null, exif.SubsecTime);
            Assert.AreEqual(null, exif.UserComment);
            Assert.AreEqual(230, exif.XResolution.Numerator);
            Assert.AreEqual(TiffYCbCrPosition.Centered, exif.YCbCrPositioning);
            Assert.AreEqual(null, exif.YCbCrSubSampling);
            Assert.AreEqual(230, exif.YResolution.Numerator);

            exif.IterateProperties();
            //Tidy up
            bmp.Dispose();
        }

        [Test]
        public void TestExifPropertiesTest2()
        {
            Bitmap bmp = new Bitmap("Samples/Test2.jpg");
            Exif exif = new Exif(bmp);

            Assert.AreEqual(null, exif.Artist);
            Assert.AreEqual(null, exif.BitsPerSample);
            Assert.AreEqual(ExifColorSpace.sRGB, exif.ColorSpace);
            Assert.AreEqual(TiffCompression.NotSpecified, exif.Compression);
            Assert.AreEqual(null, exif.Copyright);
            Assert.AreEqual(new DateTime(2001, 09, 12, 17, 03, 17), exif.DateTimeDigitized);
            Assert.AreEqual(new DateTime(2001, 09, 12, 17, 03, 17), exif.DateTimeOriginal);
            Assert.AreEqual("0210", exif.ExifVersion);
            Assert.AreEqual(ExifExposureProgram.NormalProgram, exif.ExposureProgram);
            Assert.AreEqual(new DateTime(2001, 09, 12, 17, 03, 17), exif.FileChangeDateTime);
            Assert.AreEqual("0100", exif.FlashpixVersion);
            Assert.AreEqual(null, exif.GPSData);
            Assert.AreEqual("OLYMPUS DIGITAL CAMERA         ", exif.ImageDescription);
            Assert.AreEqual(null, exif.ImageHeight);
            Assert.AreEqual(null, exif.ImageUniqueId);
            Assert.AreEqual(null, exif.ImageWidth);
            Assert.AreEqual(4084, exif.JpegInterchangeFormat);
            Assert.AreEqual(3951, exif.JpegInterchangeFormatLength);
            Assert.AreEqual("OLYMPUS OPTICAL CO.,LTD", exif.Make);
            //Just test that the content is the same length
            Assert.AreEqual(460, exif.MakerNote.Length);
            Assert.AreEqual("C2100UZ", exif.Model);
            Assert.AreEqual(TiffOrientation.TopLeft, exif.Orientation);
            Assert.AreEqual(TiffPhotometricInterpolation.NotSpecified, exif.PhotometricInterpolation);
            Assert.AreEqual(1600, exif.PixelXDimension);
            Assert.AreEqual(1200, exif.PixelYDimension);
            Assert.AreEqual(TiffPlanarConfiguration.NotSpecified, exif.PlanarConfiguration);
            Assert.AreEqual(TiffResolutionUnit.Inches, exif.ResolutionUnit);
            Assert.AreEqual(null, exif.RowsPerStrip);
            Assert.AreEqual(null, exif.SamplesPerPixel);
            Assert.AreEqual("v352p-75", exif.Software);
            Assert.AreEqual(null, exif.StripByteCounts);
            Assert.AreEqual(null, exif.StripOffsets);
            Assert.AreEqual(null, exif.SubsecDigitized);
            Assert.AreEqual(null, exif.SubsecOriginal);
            Assert.AreEqual(null, exif.SubsecTime);
            Assert.AreEqual(125, exif.UserComment.Length);
            Assert.AreEqual(72, exif.XResolution.Numerator);
            Assert.AreEqual(TiffYCbCrPosition.CoSited, exif.YCbCrPositioning);
            Assert.AreEqual(null, exif.YCbCrSubSampling);
            Assert.AreEqual(72, exif.YResolution.Numerator);

            exif.IterateProperties();
            //Tidy up
            bmp.Dispose();
        }

        [Test]
        public void TestExifPropertiesTest3()
        {
            Bitmap bmp = new Bitmap("Samples/Test3.jpg");
            Exif exif = new Exif(bmp);

            Assert.AreEqual(null, exif.Artist);
            Assert.AreEqual(null, exif.BitsPerSample);
            Assert.AreEqual(ExifColorSpace.sRGB, exif.ColorSpace);
            Assert.AreEqual(TiffCompression.NotSpecified, exif.Compression);
            Assert.AreEqual(null, exif.Copyright);
            Assert.AreEqual(null, exif.DateTimeDigitized);
            Assert.AreEqual(null, exif.DateTimeOriginal);
            Assert.AreEqual("0220", exif.ExifVersion);
            Assert.AreEqual(ExifExposureProgram.NotDefined, exif.ExposureProgram);
            Assert.AreEqual(new DateTime(2006, 11, 29, 12,52,32), exif.FileChangeDateTime);
            Assert.AreEqual("0100", exif.FlashpixVersion);
            Assert.AreEqual("untitled", exif.ImageDescription);
            Assert.AreEqual(null, exif.ImageHeight);
            Assert.AreEqual(null, exif.ImageUniqueId);
            Assert.AreEqual(null, exif.ImageWidth);
            Assert.AreEqual(null, exif.JpegInterchangeFormat);
            Assert.AreEqual(null, exif.JpegInterchangeFormatLength);
            Assert.AreEqual("SHARP", exif.Make);
            //Just test that the content is the same length
            Assert.AreEqual(null, exif.MakerNote);
            Assert.AreEqual("904SH", exif.Model);
            Assert.AreEqual(TiffOrientation.TopLeft, exif.Orientation);
            Assert.AreEqual(TiffPhotometricInterpolation.NotSpecified, exif.PhotometricInterpolation);
            Assert.AreEqual(240, exif.PixelXDimension);
            Assert.AreEqual(320, exif.PixelYDimension);
            Assert.AreEqual(TiffPlanarConfiguration.NotSpecified, exif.PlanarConfiguration);
            Assert.AreEqual(TiffResolutionUnit.Inches, exif.ResolutionUnit);
            Assert.AreEqual(null, exif.RowsPerStrip);
            Assert.AreEqual(null, exif.SamplesPerPixel);
            Assert.AreEqual(null, exif.Software);
            Assert.AreEqual(null, exif.StripByteCounts);
            Assert.AreEqual(null, exif.StripOffsets);
            Assert.AreEqual(null, exif.SubsecDigitized);
            Assert.AreEqual(null, exif.SubsecOriginal);
            Assert.AreEqual(null, exif.SubsecTime);
            Assert.AreEqual(null, exif.UserComment);
            Assert.AreEqual(72, exif.XResolution.Numerator);
            Assert.AreEqual(TiffYCbCrPosition.CoSited, exif.YCbCrPositioning);
            Assert.AreEqual(null, exif.YCbCrSubSampling);
            Assert.AreEqual(72, exif.YResolution.Numerator);

            //Test GPS Data
            Assert.AreEqual(new byte[] {2,2, 0,0}, exif.GPSData.VersionId);
            //Latitude tests
            Assert.AreEqual(ProtocolLibrary.GPS.GPSReference.N, exif.GPSData.Latitude.Reference);

            //Test Degrees Lat
            Assert.AreEqual(34, exif.GPSData.Latitude.Degrees);

            //Test Minutes Lat
            Assert.AreEqual(40, exif.GPSData.Latitude.Minutes);

            //Test Seconds Lat
            Assert.AreEqual(27.3799m, exif.GPSData.Latitude.Seconds);

            Assert.AreEqual("34°40'27.3799\"N", exif.GPSData.Latitude.ToString());
            Assert.AreEqual(34.67427, Math.Round(exif.GPSData.Latitude.ToDecimal(), 5));
            
            //Longitude tests
            Assert.AreEqual(ProtocolLibrary.GPS.GPSReference.E, exif.GPSData.Longitude.Reference);

            //Test Degrees Lat
            Assert.AreEqual(135, exif.GPSData.Longitude.Degrees);

            //Test Minutes Lat
            Assert.AreEqual(29, exif.GPSData.Longitude.Minutes);

            //Test Seconds Lat
            Assert.AreEqual(41.07m, exif.GPSData.Longitude.Seconds);

            Assert.AreEqual("135°29'41.07\"E", exif.GPSData.Longitude.ToString());
            Assert.AreEqual(135.49474, Math.Round(exif.GPSData.Longitude.ToDecimal(), 5));

            //Test Altitude
            Assert.AreEqual(ProtocolLibrary.GPS.GPSAltitudeRef.SeaLevelOrAbove, exif.GPSData.AltitudeRef);
            Assert.AreEqual(162.499m, exif.GPSData.Altitude);

            //Test DateTimeStamp
            Assert.AreEqual(new DateTime(2006, 11, 29, 3, 52, 32), exif.GPSData.UtcDateTimeStamp);

            //Test Other Properties
            Assert.AreEqual(null, exif.GPSData.Satellites);
            Assert.AreEqual(ProtocolLibrary.GPS.GPSStatus.NotSpecified, exif.GPSData.Status);
            Assert.AreEqual(ProtocolLibrary.GPS.GPSMeasureMode.NotSpecified, exif.GPSData.MeasureMode);
            Assert.AreEqual("WGS-84", exif.GPSData.MapDatum);
            
            exif.IterateProperties();
            //Tidy up
            bmp.Dispose();
        }
    }
}
